package com.framework.util.datasource;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.sql.DriverManager;
import java.util.Properties;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.SQLExec;
import org.apache.tools.ant.types.EnumeratedAttribute;
import com.framework.entity.LogDBFormMap;
import com.framework.util.Common;
import com.mysql.jdbc.Connection;

public class InvokeBatUtil {
	private static InvokeBatUtil invokeBatUtil = null;
	Logger logger = LogManager.getLogger();

	public static InvokeBatUtil getInvokeBatUtil() {
		if (invokeBatUtil == null) {
			invokeBatUtil = new InvokeBatUtil();
			return invokeBatUtil;
		} else {
			return invokeBatUtil;
		}
	}

	private InvokeBatUtil() {

	}

	/**
	 * linux shell 与 windows bat 是一样的
	 * 
	 * @author 李品良:
	 * @version 创建时间：2016年7月18日 上午11:20:35
	 * @param batName
	 * @return code 0 ,才是成功，其他都是失败
	 * @throws Exception
	 */
	public int runbat(String batName) throws Exception {
		int code = 0;
		URL pathbak = getClass().getResource(batName);
		batName = pathbak.getPath();
		if (batName == null) {
			batName = "/home/ftpdeng1/Java/hewke-con/newDB.sh";// 这里必须要给文件赋权限
		}
		return code = runBat(batName);
	}

	public int runBat(String batName) throws Exception {
		LogDBFormMap LogDBFormMap = new LogDBFormMap();

		int code = 0;
		try {
			Process ps = Runtime.getRuntime().exec(batName);
			InputStream in = ps.getInputStream();
			int c;
			while ((c = in.read()) != -1) {
				// System.out.print(c);// 如果你不需要看输出，这行可以注销掉
			}
			in.close();
			code = ps.waitFor();
			System.out.println(code);
			if (code == 0) {
				System.out.println("创建数据库成功");
			} else {
				System.out.println("创建数据库失败======失败代码为==" + code);
			}
		} catch (IOException ioe) {
			System.out.println("文件读取失败");
			ioe.printStackTrace();
		} catch (InterruptedException e) {
			System.out.println("远程创建数据库失败");
			e.printStackTrace();
		}
		LogDBFormMap.save();
		System.out.println("child thread done");
		return code;
	}

	public void saveShell(String content) throws Exception {
		String shFilePath=EnvironmentFileInfo.sql_linux.getProperty("shFilePath");
		File file = new File(shFilePath);
		// if file doesnt exists, then create it
		FileWriter fw = new FileWriter(file.getAbsoluteFile());
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write(content);
		bw.close();

		logger.warn(content+"done");
		System.out.println("Done");
	}

	
	public int runBatFromStr(String content) throws Exception {
		LogDBFormMap LogDBFormMap = new LogDBFormMap();

		String line = "";
		int code = 0;
		try {
			Process ps = Runtime.getRuntime().exec(content);
			code = ps.waitFor();
			InputStream inputStream = ps.getErrorStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

			while ((line = bufferedReader.readLine()) != null) {
				line += "<ERREO>";
				System.out.println("<ERREO>");
				System.out.println(line);
				System.out.println("<ERREO>");
				line += "<ERREO>";

			}
			logger.warn(line);
			System.out.println(code);

			inputStream.close();
			if (code == 0) {
				System.out.println("创建数据库成功");
			} else {
				logger.warn("创建数据库失败======失败代码为==" + code + "               sql为:" + content);
				System.out.println("创建数据库失败======失败代码为==" + code);
				LogDBFormMap.put("description",
						line + "创建数据库失败======失败代码为==" + code + "               sql为:" + content + "远程创建数据库失败");
			}
		} catch (IOException ioe) {
			System.out.println("文件读取失败");
			logger.warn("创建数据库失败======失败代码为==" + code + "               sql为:" + content);
			LogDBFormMap.put("description", line + "创建数据库失败======失败代码为==" + code);
			ioe.printStackTrace();
		} catch (InterruptedException e) {
			System.out.println("远程创建数据库失败");
			logger.warn("创建数据库失败======失败代码为==" + code + "               sql为:" + content);
			LogDBFormMap.put("description", line + "创建数据库失败======失败代码为==" + code);
			e.printStackTrace();
		}
		System.out.println("child thread done");
		if (LogDBFormMap.containsKey("description")) {
			LogDBFormMap.save();
		}
		return code;
	}

	public int runBatFromStr(String[] content) {
		int code = 0;
		try {

			Process ps = Runtime.getRuntime().exec(content);

			InputStream inputStream = ps.getErrorStream();
			InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

			System.out.println("<ERREO>");
			String line = null;
			while ((line = bufferedReader.readLine()) != null) {
				System.out.println(line);
			}
			System.out.println("<ERREO>");
			inputStream.close();

			code = ps.waitFor();
			System.out.println(code);
			if (code == 0) {
				System.out.println("创建数据库成功");
			} else {
				logger.warn("创建数据库失败======失败代码为==" + code + "               sql为:" + content);
				System.out.println("创建数据库失败======失败代码为==" + code);

			}
		} catch (IOException ioe) {
			System.out.println("文件读取失败");
			ioe.printStackTrace();
		} catch (InterruptedException e) {
			System.out.println("远程创建数据库失败");
			e.printStackTrace();
		}
		System.out.println("child thread done");
		return code;
	}

	public int runBatFromStrReader(String content) {
		int code = 0;
		try {
			Process ps = Runtime.getRuntime().exec(content);
			InputStream in = ps.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(in, "UTF-8");
			BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
			String str = null;
			String lineTXT = null;
			lineTXT = bufferedReader.readLine();
			while ((lineTXT = bufferedReader.readLine()) != null) {
				str += lineTXT.toString();
			}
			inputStreamReader.close();
			in.close();
			code = ps.waitFor();
			System.out.println(code);
			if (code == 0) {
				System.out.println("创建数据库成功");
			} else {
				System.out.println("创建数据库失败======失败代码为==" + code + "               sql为:" + content);
			}
		} catch (IOException ioe) {
			System.out.println("文件读取失败");
			ioe.printStackTrace();
		} catch (InterruptedException e) {
			System.out.println("远程创建数据库失败");
			e.printStackTrace();
		}
		System.out.println("child thread done");
		return code;
	}

	public String runJavaScript1(String sqlpath) throws Exception {
		try {
			Properties props = Resources.getResourceAsProperties("jdbc.properties");
			String url = props.getProperty("jdbc.url");
			String driver = props.getProperty("jdbc.driverClass");
			String username = props.getProperty("jdbc.username");
			String password = props.getProperty("jdbc.password");
			Class.forName(driver).newInstance();
			Connection conn = (Connection) DriverManager.getConnection(url, username, password);
			ScriptRunner runner = new ScriptRunner(conn);
			runner.setErrorLogWriter(null);
			runner.setLogWriter(null);
			runner.setSendFullScript(false);
			File file = new File(sqlpath);
			if (file.exists()) {
				FileInputStream fileInputStream = new FileInputStream(sqlpath);
				InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

				runner.runScript(inputStreamReader);
				inputStreamReader.close();
				runner.closeConnection();
				System.out.println("runJavaScript1===成功==" + sqlpath);
			} else {
				System.out.println("文件不存在，请检测路径");
				return "failed";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "初始化失败！请联系管理员" + e;
		}

		return "true";
	}

	public String runJavaScript2(String sqlpath) throws Exception {
		try {
			Properties props = Resources.getResourceAsProperties("jdbc.properties");
			String url = props.getProperty("jdbc.url2");
			String driver = props.getProperty("jdbc.driverClass2");
			String username = props.getProperty("jdbc.username2");
			String password = props.getProperty("jdbc.password2");
			Class.forName(driver).newInstance();
			Connection conn = (Connection) DriverManager.getConnection(url, username, password);
			ScriptRunner runner = new ScriptRunner(conn);
			runner.setErrorLogWriter(null);
			runner.setLogWriter(null);
			runner.setSendFullScript(false);
			File file = new File(sqlpath);
			if (file.exists()) {
				FileInputStream fileInputStream = new FileInputStream(sqlpath);
				InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

				runner.runScript(inputStreamReader);
				inputStreamReader.close();
				runner.closeConnection();
				System.out.println("runJavaScript2===成功==" + sqlpath);
			} else {
				System.out.println("文件不存在，请检测路径");
				return "failed";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "初始化失败！请联系管理员" + e;
		}

		return "true";
	}

	public String runJavaScript2(String sqlpath, String url) throws Exception {
		try {
			Properties props = Resources.getResourceAsProperties("jdbc.properties");
			String driver = props.getProperty("jdbc.driverClass2");
			String username = props.getProperty("jdbc.username2");
			String password = props.getProperty("jdbc.password2");

			Class.forName(driver).newInstance();
			Connection conn = (Connection) DriverManager.getConnection(url, username, password);
			ScriptRunner runner = new ScriptRunner(conn);
			runner.setErrorLogWriter(null);
			runner.setLogWriter(null);
			runner.setSendFullScript(false);
			File file = new File(sqlpath);
			if (file.exists()) {
				FileInputStream fileInputStream = new FileInputStream(sqlpath);
				InputStreamReader in = new InputStreamReader(fileInputStream, "UTF-8");
				runner.runScript(in);

				in.close();
				runner.closeConnection();

				System.out.println(url + "runJavaScript===成功" + sqlpath);
			} else {
				System.out.println("文件不存在，请检测路径");
				return "failed";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "初始化失败！请联系管理员" + e;
		}

		return "true";
	}

	public String runJavaScript(String sqlpath, String username, String password, String url) throws Exception {
		try {

			JDBCSource jdbcTest = new JDBCSource();
			jdbcTest.changeJDBC(url, username, password);

			Connection conn = (Connection) jdbcTest.getConnection();
			ScriptRunner runner = new ScriptRunner(conn);
			runner.setErrorLogWriter(null);
			runner.setLogWriter(null);
			runner.setSendFullScript(false);
			File file = new File(sqlpath);
			if (file.exists()) {
				FileInputStream fileInputStream = new FileInputStream(sqlpath);
				InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");

				runner.runScript(inputStreamReader);
				inputStreamReader.close();
				runner.closeConnection();

				System.out.println("runJavaScript===成功");
			} else {
				System.out.println("文件不存在，请检测路径");
				return "failed";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "初始化失败！请联系管理员" + e;
		}

		return "true";
	}

	/**
	 * 读取文件内容
	 * 
	 * @param inputStreamReader
	 * @throws IOException
	 */
	public void readInputStream(InputStreamReader inputStreamReader) throws IOException {
		InputStreamReader read = inputStreamReader;
		BufferedReader bufferedReader = new BufferedReader(read);
		String lineTXT = null;
		String str = "";
		int i = 0;
		while ((lineTXT = bufferedReader.readLine()) != null && i < 5) {
			str += lineTXT.toString() + "\r\n";
			i++;
		}
		System.out.println(str);
	}

	public void runAntScript(String sqlpath) throws IOException {
		SQLExec sqlExec = new SQLExec();
		// 设置数据库参数
		Properties props = Resources.getResourceAsProperties("jdbc.properties");
		String url = props.getProperty("jdbc.url");
		String driver = props.getProperty("jdbc.driverClass");
		String username = props.getProperty("jdbc.username");
		String password = props.getProperty("jdbc.password");
		sqlExec.setDriver(driver);
		sqlExec.setUrl(url);
		sqlExec.setUserid(username);
		sqlExec.setPassword(password);
		// 要执行的脚本
		File file = new File(sqlpath);
		sqlExec.setSrc(file);
		// 有出错的语句该如何处理
		sqlExec.setOnerror((SQLExec.OnError) (EnumeratedAttribute.getInstance(SQLExec.OnError.class, "abort")));
		sqlExec.setPrint(true); // 设置是否输出
		// 输出到文件 sql.out 中；不设置该属性，默认输出到控制台
		sqlpath = sqlpath.replace("con1000.sql", "output.log");
		sqlExec.setOutput(new File(sqlpath));
		sqlExec.setProject(new Project()); // 要指定这个属性，不然会出错
		sqlExec.execute();
		System.out.println("runAntScript===成功");
	}

	public void runAntScript(String sqlpath, String username, String password, String url) throws IOException {
		SQLExec sqlExec = new SQLExec();
		// 设置数据库参数
		Properties props = Resources.getResourceAsProperties("jdbc.properties");
		String driver = props.getProperty("jdbc.driverClass");
		sqlExec.setDriver(driver);
		sqlExec.setUrl(url);
		sqlExec.setUserid(username);
		sqlExec.setPassword(password);
		// 要执行的脚本
		File file = new File(sqlpath);
		sqlExec.setSrc(file);
		// 有出错的语句该如何处理
		sqlExec.setOnerror((SQLExec.OnError) (EnumeratedAttribute.getInstance(SQLExec.OnError.class, "abort")));
		sqlExec.setPrint(true); // 设置是否输出
		// 输出到文件 sql.out 中；不设置该属性，默认输出到控制台
		// sqlpath = sqlpath.replace("con1000.sql", "output.log");
		// sqlExec.setOutput(new File(sqlpath));
		sqlExec.setProject(new Project()); // 要指定这个属性，不然会出错
		sqlExec.execute();
		System.out.println("runAntScript===成功");
	}

	public int writeAndRunBat(String content, String filepath) {
		RunsqlUtils runsqlUtils = new RunsqlUtils();
		filepath = runsqlUtils.writeSql(content, filepath);
		int code = 0;
		try {
			code = runBat(filepath);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return code;
	}

}